package com.zxmr.action;

/**
 * this class is not thread safe
 * 
 * in default the message send to the exchange which has the same name with routing key
 */
import java.io.IOException;
import java.util.Map;

import com.alibaba.fastjson.annotation.JSONField;
import com.alibaba.fastjson.serializer.JSONSerializer;
import com.alibaba.fastjson.serializer.SerializeWriter;
import com.rabbitmq.client.AMQP;
import com.rabbitmq.client.Channel;
import com.zxmr.domain.account.User;
import com.zxmr.domain.component.Action;
import com.zxmr.fastjson.filter.AccountSimpleSerializeFilter;
import com.zxmr.rabbit.ChannelFactory;

public class Request{

	String id;
	
	Session session;
	
	User account;
	
	@JSONField(serialize=false)
	Action action;

	RequestPayload payload;
	
	@JSONField(serialize=false)
	AMQP.BasicProperties requestProperties;
	
	boolean needResponse = false;
	
	boolean internal = false;
	
	public Request()
	{
		
	}
	private byte[] encode()
	{
		SerializeWriter sw = new SerializeWriter();
		JSONSerializer serializer = new JSONSerializer(sw);
		serializer.getPropertyFilters().add(new AccountSimpleSerializeFilter());
		
		serializer.write(this);
		return sw.toBytes("UTF-8");
	}
	public String getId() {
		return id;
	}
	public void setId(String id) {
		this.id = id;
	}
	public Session getSession() {
		return session;
	}
	public void setSession(Session session) {
		this.session = session;
	}
	
	@JSONField(serialize=false)
	public Map<String, String> getRequestParameters() {
		return payload.getParameters();
	}
	
	
	public User getAccount() {
		return account;
	}
	public void setAccount(User account) {
		this.account = account;
	}
	@JSONField(serialize=false)
	public String getRequestUrl() {
		return payload.getUrl();
	}
	
	public boolean send(String sourceQueue,String targetQueue) throws IOException
	{
		// get one channel
		Channel channel = ChannelFactory.createChannel();
		if(channel == null)
		{
			return false;
		}
		// send to the queue which owned by the component with direct manner
		channel.exchangeDeclare(targetQueue, "direct");

		byte[] data = this.encode();
	
		/*
		 * try to register id in to the monitor
		 */
		
		// set the sequence id and source queue name
		requestProperties = buildProp(id,sourceQueue);
		
		/*
		 * in default the message send to the exchange which has the same name with routing key
		 */
		channel.basicPublish(targetQueue,targetQueue, requestProperties,data);
		channel.close();
		return true;
	}
	private AMQP.BasicProperties buildProp(String correlationId,String srcQueue)
	{
		AMQP.BasicProperties.Builder builder = new AMQP.BasicProperties.Builder();
		return builder.correlationId(correlationId).replyTo(srcQueue).build();
	}
	public AMQP.BasicProperties getRequestProperties() {
		return requestProperties;
	}
	public void setRequestProperties(AMQP.BasicProperties requestProperties) {
		this.requestProperties = requestProperties;
	}
	public boolean isNeedResponse() {
		return needResponse;
	}
	public void setNeedResponse(boolean needResponse) {
		this.needResponse = needResponse;
	}
	public Action getAction() {
		return action;
	}
	public void setAction(Action action) {
		this.action = action;
	}
	public RequestPayload getPayload() {
		return payload;
	}
	public void setPayload(RequestPayload payload) {
		this.payload = payload;
	}
	public boolean isInternal() {
		return internal;
	}
	public void setInternal(boolean internal) {
		this.internal = internal;
	}
	
}
